题目1：**题目描述**

评定奖学金。奖学金评比方法如下：先计算加权成绩，其中k为课程数，然后按照加权成绩排序（规定所有同学的加权成绩各不相同），根据学生的数量取前10%的同学获得一等奖学金（获奖人数向上取整），输出一等奖学金的学生姓名。

**输入说明：**
第一行输入整数k
第二行依次输入k个数据
第三行输入一个整数N
从第四行开始依次输入N名同学的成绩数据（数据格式：姓名 K门课的整数成绩）

**输出说明：**
输出获一等奖的学生姓名，有多名同学则用单个空格隔开。

**输入样例：**
5
2.0 1.0 2.0 3.0 0.5
5
XM 75 90 80 80 90
ZB 65 80 70 70 85
XH 70 80 70 75 90
WJ 80 85 85 85 90
LH 80 90 90 80 85

**输出样例：**
WJ

#include<iostream>
#include<vector>
#include<cmath>  
using namespace std;

int main()
{
    int k;
    cin>>k;
    vector<double> scord(k);
    for(int i=0;i<k;i++)
    {
        cin>>scord[i];
    }
    int N;
    cin>>N;
    vector<string> name(N);
    vector<vector<double>> board(N,vector<double>(k));
    vector<double> sumScord(N);
    for(int i=0;i<N;i++)
    {
        cin>>name[i];
        for(int j=0;j<k;j++)
        {
            cin>>board[i][j];
            sumScord[i]+=scord[j]*board[i][j];
        }
    }
    vector<int> index(N);
    for(int i=0;i<N;i++)
    {
        index[i]=i;
    }
    sort(index.begin(),index.end(),[&](int a,int b){
        return sumScord[a]>sumScord[b];
    });
    int count=ceil(N*0.1);
    for(int i=0;i<count;i++)
    {
        cout<<name[index[i]]<<" ";
    }
    return 0;
}

题目2：
**题目描述**

已知结点元素值为正整数且值不相同的一棵二叉树。该二叉树通过给出其先序遍历序列和中序遍历序列构造而成。输入一个整数x；编写程序判断求出x的左子树所有结点中的最大值（若x不在树上输出-1）。

**输入说明：**
第一行输入某二叉树的先序遍历序列
第二行输入该二叉树的中序遍历序列
第三行输入正整数x

**输出说明：**
若x在树上输出其左子树中所有结点中的最大值（如果左子树为空，输出x本身）；如果x不在树上则输出-1；

**输入样例1：**
20 15 10 12 18 16 17 25 30
10 12 15 16 17 18 20 25 30
15

**输出案例1：**
12

**输入样例2：**
20 15 10 12 18 16 17 25 30
10 12 15 16 17 18 20 25 30
10

**输出案例2：**
10

**输入样例3：**
20 15 10 12 18 16 17 25 30
10 12 15 16 17 18 20 25 30
14

**输出案例3：**
-1

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder, 
                    int preStart, int preEnd, 
                    int inStart, int inEnd) {
    if (preStart > preEnd) return NULL;
    
    int rootVal = preorder[preStart];
    TreeNode* root = new TreeNode(rootVal);
    
    int inIndex = inStart;
    while (inorder[inIndex] != rootVal) inIndex++;
    
    int leftSize = inIndex - inStart;
    
    root->left = buildTree(preorder, inorder, 
                          preStart + 1, preStart + leftSize, 
                          inStart, inIndex - 1);
    root->right = buildTree(preorder, inorder, 
                           preStart + leftSize + 1, preEnd, 
                           inIndex + 1, inEnd);
    return root;
}

TreeNode* findNode(TreeNode* root, int x) {
    if (!root) return NULL;
    if (root->val == x) return root;
    TreeNode* leftSearch = findNode(root->left, x);
    if (leftSearch) return leftSearch;
    return findNode(root->right, x);
}

int findMaxInSubtree(TreeNode* root) {
    if (!root) return -1;
    int maxVal = root->val;
    if (root->left) 
        maxVal = max(maxVal, findMaxInSubtree(root->left));
    if (root->right) 
        maxVal = max(maxVal, findMaxInSubtree(root->right));
    return maxVal;
}

int main() {
    vector<int> preorder, inorder;
    int num;
    
    // 读取先序
    while (cin >> num) {
        preorder.push_back(num);
        if (cin.get() == '\n') break;
    }
    // 读取中序
    while (cin >> num) {
        inorder.push_back(num);
        if (cin.get() == '\n') break;
    }
    
    int x;
    cin >> x;
    
    TreeNode* root = buildTree(preorder, inorder, 0, preorder.size()-1, 0, inorder.size()-1);
    
    TreeNode* target = findNode(root, x);
    if (!target) {
        cout << -1 << endl;
    } else {
        if (target->left == NULL) {
            cout << x << endl;
        } else {
            cout << findMaxInSubtree(target->left) << endl;
        }
    }
    
    return 0;
}